module GYLite
{
				
		
	/**UIComponent是有组件的基础组件，具有布局与监听视图变化功能，
	 * 拥有视图改变的事件通知,以便通知子级父级容器变化，如只需要布局的普通容器建议使用GYSprite*/
	export class GYUIComponent extends GYSprite
	{
		protected _boundRect:egret.Rectangle;
		protected _elementsRect:egret.Rectangle;
		public $paddingLeft:number;
		public $paddingRight:number;
		public $paddingTop:number;
		public $paddingBottom:number;
		public $contentWidth:number;
		public $contentHeight:number;		
		public constructor()
		{
			super();
			var s = this;
			s._boundRect = new egret.Rectangle;
			s._elementsRect = new egret.Rectangle;
			s.$paddingLeft=0;
			s.$paddingRight=0;
			s.$paddingTop=0;
			s.$paddingBottom=0;
			s.$contentWidth=0;
			s.$contentHeight=0;
		}
		/**视图改变，派发VIEWCHANGE事件并通知父级GYUIComponent调用s.viewChange*/
		public viewChange():void
		{var s = this;
			s.getAllBounds(this);
			s.getElementsBounds(this);
			s.layout();
			if(s.hasEventListener(GYViewEvent.VIEWCHANGE))
				s.dispatchEvent(new GYViewEvent(GYViewEvent.VIEWCHANGE))
			if(s.viewChangeCallParent && (<any>s.parent).viewChange!=null)
                (<any>s.parent).viewChange();
		}
		public addElement(child:IGYDisplay):IGYDisplay
		{var s = this;
			if(s.elementVec.length > 0 && s.elementVec[s.elementVec.length-1] == child)
				return child;
			s.invalidDisplay();			
			if(child.parent)
				(child.parent as GYSprite).delElement(child);
			s.elementVec.push(child);			
			s.addChild(<egret.DisplayObject><any>child);
			child.addLayout(<GYUIComponent>child.getLayoutContainer());
			return child;
		}
		public addElementAt(child:IGYDisplay, index:number):IGYDisplay
		{var s = this;
			if(index < s.elementVec.length && s.elementVec[index] == child)
				return child;
			s.invalidDisplay();
			if(index > -1)
			{				
				if(child.parent)
					(child.parent as GYSprite).delElement(child);
				s.elementVec.splice(index,0,child);
			}			
			s.addChildAt(<egret.DisplayObject><any>child,index);
			child.addLayout(<GYUIComponent>child.getLayoutContainer());
			return child;
		}
		public removeElement(child:IGYDisplay):IGYDisplay
		{var s = this;
			s.invalidDisplay();
			s.delElement(child);
			s.removeChild(<egret.DisplayObject><any>child);
			child.addLayout(null);
			return child;
		}
		public removeElementAt(index:number):IGYDisplay
		{var s = this;
			var gySp:IGYDisplay=s.elementVec[index];
			s.invalidDisplay();
			s.elementVec.splice(index,1);
			s.removeChild(<egret.DisplayObject><any>gySp);
			gySp.addLayout(null);
			return gySp;
		}
		public set paddingLeft(val:number)
		{
			this.set_paddingLeft(val);
		}
		public set paddingRight(val:number)
		{
			this.set_paddingRight(val);
		}
		public set paddingTop(val:number)
		{
			this.set_paddingTop(val);
		}
		public set paddingBottom(val:number)
		{
			this.set_paddingBottom(val);
		}
		public set_paddingLeft(val:number):void
		{
			let s = this;
			if(s.$paddingLeft == val)
				return;
			s.$setX(s.x - s.$paddingLeft + val);			
			s.$paddingLeft = val;
			s.invalidDisplay();
		}
		public set_paddingRight(val:number):void
		{
			let s = this;
			if(s.$paddingRight == val)
				return;
			s.$paddingRight = val;
			s.invalidDisplay();
		}
		public set_paddingTop(val:number):void
		{
			let s = this;
			if(s.$paddingTop == val)
				return;			
			s.$setY(s.y - s.$paddingTop + val);			
			s.$paddingTop = val;
			s.invalidDisplay();
		}
		public set_paddingBottom(val:number):void
		{
			let s = this;
			if(s.$paddingBottom == val)
				return;
			s.$paddingBottom = val;
			s.invalidDisplay();
		}
		public updateView():void
		{var s = this;
			if(s._invalidZIndex)
			{
				s.validZIndex();
				s._invalidZIndex = false;
			}
			if(s._invalidDisplay)
			{
				s.viewChange();
				s._invalidDisplay = false;
			}
			if(s.hasEventListener(GYViewEvent.UPDATE_COMPLETE))
				s.dispatchEvent(new GYViewEvent(GYViewEvent.UPDATE_COMPLETE));
		}
		/**左边距*/
		public get paddingLeft():number
		{
			return this.$paddingLeft;
		}
		/**右边距*/
		public get paddingRight():number
		{
			return this.$paddingRight;
		}
		/**上边距*/
		public get paddingTop():number
		{
			return this.$paddingTop;
		}
		/**底边距*/
		public get paddingBottom():number
		{
			return this.$paddingBottom;
		}
		public set x(val:number)
		{
			let s = this;
			if(!s.$setX(val + s.$paddingLeft))
				return;			
			if(s.posCallUpdate)
				s.invalidDisplay();
		}
		public get x():number
		{
			return this.$x;
		}
		public set y(val:number)
		{
			let s = this;	
			if(!s.$setY(val + s.$paddingTop))
				return;				
			if(s.posCallUpdate)
				s.invalidDisplay();
		}
		public get y():number
		{
			return this.$y;
		}
		// public set width(val:number)
		// {
		// 	this.set_width(val);
		// }		
		// public get width():number
		// {
		// 	return this.get_width();
		// }
		public set_width(val:number):boolean
		{
			let s = this;			
			if(s.$width == val)
				return false;			
			s.$width = val;
			s.invalidDisplay();			
			return true;
		}
		public get_width():number
		{
			let s = this;
			return super.get_width() + s.$paddingTop + s.$paddingBottom;
		}		
		// public set height(val:number)
		// {			
		// 	this.set_height(val);
		// }
		// public get height():number
		// {
		// 	return this.get_height();
		// }
		public set_height(val:number):boolean
		{
			let s = this;	
			if(s.$height == val)
				return false;
			s.$height = val;
			s.invalidDisplay();	
			return true;
		}		
		public get_height():number
		{
			let s = this;
			return super.get_height() + s.$paddingTop + s.$paddingBottom;
		}
		
		/**不带边距的宽度*/
		public get baseWidth():number
		{
			return super.get_width();
		}
		/**不带边距的高度*/
		public get baseHeight():number
		{
			return super.get_height();
		}
		//重写缩放 +滚动条判断
		public set scaleX(val:number)
		{var s = this;			
			if(s.$scaleX == val)
				return;
			s.$setScaleX(val);			
			s.invalidDisplay();
		}
		public get scaleX():number
		{
			return this.$scaleX;			
		}
		public set scaleY(val:number)
		{var s = this;			
			if(s.scaleY == val)
				return;
			s.$setScaleY(val);			
			s.invalidDisplay();
		}
		public get scaleY():number
		{
			return this.$scaleY;			
		}
		/**获取element元素边框宽度*/
		public get borderWidth():number
		{var s = this;
			if(s.$width != s.$width)
				return s._elementsRect.width;
			return s.width;
		}
		/**获取element元素边框高度*/
		public get borderHeight():number
		{var s = this;
			if(s.$height != s.$height)
				return s._elementsRect.height;
			return s.height;
		}
		/**@inheritDoc
		 * 忽略s.scrollRect
		 * */
		public getAllBounds(t:IGYDisplay):egret.Rectangle
		{var s = this;
			var len:number=s.elementVec.length;
			var gySp:IGYDisplay;
			var rect:egret.Rectangle;
			if(t != this && s.scrollRect && !s.scrollRect.isEmpty())
			{
				s._boundRect.width = s.scrollRect.width;
				s._boundRect.height = s.scrollRect.height;
				s._boundRect.x = s.$x;
				s._boundRect.y = s.$y;
				return s._boundRect;
			}
			s._boundRect.bottom=s._boundRect.right=s._boundRect.y=s._boundRect.x=0;			
			while(len)
			{
				--len;
				gySp = s.elementVec[len];
				if(gySp.offLayout || !gySp.$visible || gySp.isPercentSize() || gySp.layoutMode.layoutMode == LayoutMode.RELATIVE)
					continue;
				if(gySp.width == 0)continue;
				rect = gySp.getAllBounds(t);
				if(rect.x < s._boundRect.x)
					s._boundRect.x = rect.x;
				if(rect.y < s._boundRect.y)
					s._boundRect.y = rect.y;
				if(rect.right > s._boundRect.right)
					s._boundRect.right = rect.right;
				if(rect.bottom > s._boundRect.bottom)
					s._boundRect.bottom = rect.bottom;
			}			
			s.$contentWidth = s._boundRect.x + s._boundRect.width;
			s.$contentHeight = s._boundRect.y + s._boundRect.height;
			if(t != this)
			{
				s._boundRect.x+=s.$x;
				s._boundRect.y+=s.$y;
			}
			return s._boundRect;
		}
		/**@inheritDoc*/
		public getElementsBounds(t:IGYDisplay):egret.Rectangle
		{var s = this;
			if(s.scrollRect && !s.scrollRect.isEmpty())
			{
				s._elementsRect.width = s.scrollRect.width + s.$paddingRight + s.$paddingLeft;
				s._elementsRect.height = s.scrollRect.height + s.$paddingTop + s.$paddingBottom;
				s._elementsRect.x = s.$x - s.$paddingLeft;
				s._elementsRect.y = s.$y - s.$paddingTop;
				return s._elementsRect;
			}
			var len:number=s.elementVec.length;
			var gySp:IGYDisplay;
			var rect:egret.Rectangle;			
			s._elementsRect.bottom=s._elementsRect.right=s._elementsRect.y=s._elementsRect.x=0;			
			while(len)
			{
				--len;
				gySp = s.elementVec[len];
				if(gySp.offLayout || !gySp.visible || gySp.isPercentSize() || gySp.layoutMode.layoutMode == LayoutMode.RELATIVE)
					continue;
				rect = gySp.getElementsBounds(t);
				if(rect.x < s._elementsRect.x)
					s._elementsRect.x = rect.x;
				if(rect.y < s._elementsRect.y)
					s._elementsRect.y = rect.y;
				if(rect.right > s._elementsRect.right)
					s._elementsRect.right = rect.right;
				if(rect.bottom > s._elementsRect.bottom)
					s._elementsRect.bottom = rect.bottom;				
			}
			if(t != this)
			{
				s._elementsRect.x+=s.$x;
				s._elementsRect.y+=s.$y;
			}
			s._elementsRect.width += s.$paddingRight + s.$paddingLeft;
			s._elementsRect.height += s.$paddingTop + s.$paddingBottom;
			return s._elementsRect;
		}
		/**同时设置4个边距*/		
		public setPadding(val:number):void
		{var s = this;
			s.set_paddingLeft(val);
			s.set_paddingRight(val);
			s.set_paddingBottom(val);
			s.set_paddingTop(val);
		}
		/**内容宽度*/
		public get contentWidth():number
		{var s = this;
			return s.$contentWidth;
		}
		/**内容高度*/
		public get contentHeight():number
		{var s = this;
			return s.$contentHeight;
		}
	}
}